﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Configuration;

namespace Gollie.WebCache
{
    public static class DataCache
    {
		private static MemoryCache memCache = null;

        public static T GetCacheableObject<T>(string cacheName) where T : ICacheable, new()
        {
            T obj = (T)Cache[cacheName];
            if (obj == null)
            {
                obj = new T();
                Insert(cacheName, obj, obj.Policy);
            }

            return obj;
        }

		public static T GetCacheableObject<T>(string cacheName, params object[] args) where T : ICacheable, new()
		{
			T obj = (T)Cache[cacheName];
			if (obj == null)
			{
				obj = new T();
				obj.Initialize(args);
				Insert(cacheName, obj, obj.Policy);
			}

			return obj;
		}

		public static T TryGetValue<T>(string cacheName) where T : ICacheable
		{
			return (T)Cache[cacheName];
		}

        public static void ClearAll()
        {
			memCache.Dispose();
			memCache = null;
        }

		public static MemoryCache Cache
		{
			get
			{
				if (memCache == null)
				{
					var section = (WebCacheConfigSectionHandler)ConfigurationManager.GetSection("GollieCache");
					
					memCache = new MemoryCache(section.CacheName);
					
				}

				return memCache;
			}
		}

		public static void Insert(string key, object o, DateTime absoluteExpiration)
		{
			DataCache.Insert(key, o, absoluteExpiration, null);
		}

		public static void Insert(string key, object o, DateTime absoluteExpiration, string[] dependsOn)
		{
			CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = absoluteExpiration };
			if (dependsOn != null && dependsOn.Length > 0)
			{
				policy.ChangeMonitors.Add(Cache.CreateCacheEntryChangeMonitor(dependsOn));
			}

			DataCache.Insert(key, o, policy);
		}

		public static void Insert(string key, object o, CacheItemPolicy policy)
		{
			Cache.Set(key, o, policy);
		}

		public static void Insert(string key, object o)
		{
			Cache.Set(key, o, ObjectCache.InfiniteAbsoluteExpiration);
		}
    }
}